[org 0x1000]

dw 0x55aa;魔数 用于教研

mov si, loading
call print

detect_momery:

    ;es:di 结构体的缓存位置
    mov ax, 0
    mov es, ax

    mov edi, ards_buffer


    mov edx, 0x534d4150 ;固定签名

.next:
    mov eax, 0xe820
    mov ecx, 20
    int 0x15

    jc error

    add di, cx 

    inc word [ards_count]

    cmp ebx, 0
    jnz .next
    mov si,detecting

    xor ebx, ebx
    call print

    jmp prepare_protected_mode


prepare_protected_mode:
    xchg bx, bx
    cli

    in al, 0x92
    or al, 0b10
    out 0x92, al 

    lgdt [gdt_ptr]

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp dword code_selector:protect_mode


print:
    mov ah,0x0e
.next:
    mov al,[si]
    cmp al,0
    jz .done
    int 0x10
    inc si
    jmp .next
.done:
    ret

loading:
    db "loading Onix...",10,13,0 ;\n \r end

detecting:
    db "Detecting Memory Success...",10,13,0 ;\n \r end

error:
    mov si, .msg
    call print
    hlt
    jmp $
    .msg db "Loding error...",10,13,0 ;\n \r end

[bits 32]
protect_mode:
    xchg bx, bx
    mov ax,data_selector
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

    mov esp, 0x10000

    mov byte [0xb8000], 'X'

    mov byte [0x200000], '5'

    jmp $

; typedef struct selector
; {
;     unsigned char RPL : 2; // Request PL 
;     unsigned char TI : 1; // 0  全局描述符 1 局部描述符 LDT Local 
;     unsigned short index : 13; // 全局描述符表索引
; } __attribute__((packed)) selector;
; selector 结构体有 16 位， 在 gdt 中第 0 个索引被系统占用 都是 0
code_selector equ (1 << 3)  ; 1 表示gdt的第 1 个索引，左移3位表示 RPL 和 TI 都是0
data_selector equ (2 << 3)  ; 2 表示gdt的第 2 个索引，左移3位表示 RPL 和 TI 都是0

memory_base equ 0   ;内存开始位置；基地之

;内存界限4G / 4K - 1
memory_limit equ ((1024 * 1024 *1024 * 4) / (4 * 1024)) - 1

; typedef struct pointer
; {
;     unsigned short limit; // size - 1
;     unsigned int base;    gdt的首地址
; } __attribute__((packed)) pointer;
; pointer 结构体有 48 位，其中 0 ~ 16 位表示表界限，17 ~ 47 位表示 gdt 的首地址
gdt_ptr:
    dw (gdt_end - gdt_base) - 1 ; limit = size - 1
    dd gdt_base                 ; gdt的首地址

gdt_base:
    dd 0, 0 ;null
gdt_code:
    ; limit:20  base:32
    dw memory_limit & 0xffff                        ; limit_low:16 段界限 0 ~ 15 位 (0 ~ 15) v

    dw memory_base & 0xffff                         ; base_low:16 基地址 0 ~ 15 位 (16 ~ 31) v

    db (memory_base >> 16) & 0xff                   ; base_low:8 基地址 16 ~ 23 位 (32 ~ 39) v

    db 0b_1_00_1_1_0_1_0                            ; (共8位)  present:1 + DPL:2 + segment:1 + type:4 (40 ~ 47) v
                                                    ; 1---------------------0-0------------1------------------1-0-1-0
                                                    ; P---------------------DPL------------S-------------------type--
                                                    ; 段在内存中存在------特权级0~3---数据段/代码段------------执行/读

    db 0b1_1_0_0_0000 | (memory_limit >> 16) & 0xf  ; (共8位) granularity:1 + big:1 + long_mode:1 + available:1 + limit_high:4 段界限 16 ~ 19 (48 ~ 55) v
                                                    ; 1-----------------------1------------0-----------0-----------0-0-0-0
                                                    ; G-----------------------D------------L----------AVL---------limit_high
                                                    ; 界限粒度为4K 字节------32位-----64位扩展标志--预留(无用)-----limit_high

    db (memory_base >> 24) & 0xff                   ; base_high:8 (56 ~ 63)

gdt_data:
    dw memory_limit & 0xffff
    dw memory_base & 0xffff 
    db (memory_base >> 16) & 0xff
    db 0b_1_00_1_0_0_1_0
    db 0b1_1_0_0_0000 | (memory_limit >> 16) & 0xf
    db (memory_base >> 24) & 0xff
gdt_end:

ards_count:
    dw 0
ards_buffer: